package com.local.carousel.aspect;

import com.google.common.base.Converter;
import com.local.carousel.pojo.Carousel;
import com.local.carousel.redis.RedisCache;
import com.local.common.util.PageResultUtil;
import com.local.common.util.ResultUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Carousel业务的切面方法类
 */

@Component
@Aspect
public class CarouselAdvice {

    @Autowired
    private RedisCache redisCache;


    /**
     * 后台列表页的切面方法，将数据加入redis缓存
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(public com.local.common.util.PageResultUtil com.local.carousel.service.CarouselService.getCarouselPage(..))")
    public PageResultUtil<Carousel> pageAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        PageResultUtil<Carousel> proceed = (PageResultUtil<Carousel>) proceedingJoinPoint.proceed(args);
        if (Objects.nonNull(proceed)) {
            if (proceed.getList().size() > 0) {
                for (Carousel carousel : proceed.getList()) {
                    if (carousel.getIsDeleted() == 0) {
                        redisCache.setCacheMapHashValue("carouselList", carousel.getCarouselId().toString(), carousel);
                    } else {
                        redisCache.deleteHashKey("carouselList", carousel.getCarouselId().toString());
                    }
                }
            }
        }
        return proceed;
    }


    /**
     * 后台更新业务的切面方法
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(public java.lang.Integer com.local.carousel.service.CarouselService.update(..))")
    public Integer updateAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        Carousel carousel = (Carousel) args[0];
        Integer proceed = (Integer) proceedingJoinPoint.proceed(args);
        if (proceed > 0) {
            //更新成功，则把redis中的缓存也同步更新
            if (carousel.getIsDeleted() == 0) {
                //数据状态正常，则添加到redis
                redisCache.setCacheMapHashValue("carouselList", carousel.getCarouselId().toString(), carousel);
            } else {
                //数据状态为删除，则从redis移除
                redisCache.deleteHashKey("carouselList", carousel.getCarouselId().toString());
            }

        }
        return proceed;
    }


    /**
     * 后台新增业务的切面方法
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public java.lang.Integer com.local.carousel.service.CarouselService.save(..))")
    public Integer saveAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        Carousel carousel = (Carousel) args[0];
        Integer proceed = (Integer) proceedingJoinPoint.proceed(args);
        if (proceed > 0) {
            //新增成功，则加入到redis缓存中
            if (carousel.getIsDeleted() == 0) {
                redisCache.setCacheMapHashValue("carouselList", carousel.getCarouselId().toString(), carousel);
            }
        }
        return proceed;
    }


    /**
     * 后台单个/批量删除的切面方法
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(public java.lang.Integer com.local.carousel.service.CarouselService.deleteByIds(..))")
    public Integer deleteByIdsAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        Integer[] ids = (Integer[]) args[0];
        Integer proceed = (Integer) proceedingJoinPoint.proceed(args);
        if (proceed > 0) {
            //删除成功，则从redis中移除
            Map<String, Carousel> carouselList = redisCache.getCacheMap("carouselList");
            if (Objects.nonNull(carouselList)) {
                for (Integer id : ids) {
                    redisCache.deleteHashKey("carouselList", id.toString());
                }
            }
        }
        return proceed;
    }


    /**
     * 获取Carousel列表。如果redis缓存中存在，则直接从redis缓存中获取。不存在，则从mysql中查询，同时缓存到redis
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(public java.util.List<com.local.carousel.pojo.Carousel> com.local.carousel.service.CarouselService.getCarouselList(..))")
    public List<Carousel> indexListAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Map<String, Carousel> carouselMap = redisCache.getCacheMap("carouselList");
        List<Carousel> carouselList = new ArrayList<>();
        if (Objects.nonNull(carouselMap)) {
            Set<Map.Entry<String, Carousel>> entries = carouselMap.entrySet();
            for (Map.Entry<String, Carousel> entry : entries) {
                carouselList.add(entry.getValue());
            }
        }
        if (carouselList.size() > 0) {
            return carouselList;
        } else {
            Object[] args = proceedingJoinPoint.getArgs();
            carouselList = (List<Carousel>) proceedingJoinPoint.proceed(args);
            Map<String, Carousel> collect = carouselList.stream().collect(Collectors.toMap(s -> s.getCarouselId().toString(), Function.identity(), (key1, key2) -> key2));
            redisCache.setCacheMap("carouselList", collect);
            return carouselList;
        }
    }
}
